import React from 'react'
import cssStyle from './index.module.css'
import PropTypes from 'prop-types'
import { Button, Form } from '@/component'

function imgToBase64({img, width, height, left, top, success}){
    let canvas = document.createElement('canvas')
    canvas.width = img.naturalWidth
    canvas.height = img.naturalHeight
    let context = canvas.getContext('2d')
    context.drawImage(img, 0, 0, img.naturalWidth, img.naturalHeight)

    let scale = img.naturalWidth/img.width
    let data = context.getImageData(left*scale, top*scale, width*scale, height*scale)
    let clipCanvas = document.createElement('canvas')
    clipCanvas.width = width*scale
    clipCanvas.height = height*scale
    let clipContext = clipCanvas.getContext('2d')
    clipContext.putImageData(data, 0, 0)
    clipCanvas.toBlob(res => {
        success(res)
    }, 'image/jpeg')
}

class Crop extends React.PureComponent{
    state = {
        hasImg: this.props.src ? true : false,
        w: 1,
        h: 1
    }
    mainImgRef = React.createRef()
    cropBoxRef = React.createRef()
    cropBoxViewRef = React.createRef()
    prevviewContainer = React.createRef()
    containerRef = React.createRef()
    isMouse = false
    isCropBoxMouse = false
    isPointMouse = false
    timer = null
    point = ''
    src = null
    imgInfo = {
        width: 0,
        height: 0,
        naturalWidth: 0,
        naturalHeight: 0
    }
    cropBoxInfo = {
        currentWidth: 0,
        currentHeight: 0,
        width: 0,
        height: 0,
        top: 0,
        left: 0,
        translateX: 0,
        translateY: 0,
        start: {
            x: 0,
            y: 0
        },
        current: {
            x: 0,
            y: 0
        }
    }
    pointInfo = {
        leftTop: {
            start: {
                x: 0,
                y: 0
            },
            current: {
                x: 0,
                y: 0
            }
        },
        rightTop: {
            start: {
                x: 0,
                y: 0
            },
            current: {
                x: 0,
                y: 0
            }
        },
        rightBottom: {
            start: {
                x: 0,
                y: 0
            },
            current: {
                x: 0,
                y: 0
            }
        },
        leftBottom: {
            start: {
                x: 0,
                y: 0
            },
            current: {
                x: 0,
                y: 0
            }
        },
        left: {
            start: {
                x: 0,
                y: 0
            },
            current: {
                x: 0,
                y: 0
            }
        },
        right: {
            start: {
                x: 0,
                y: 0
            },
            current: {
                x: 0,
                y: 0
            }
        },
        top: {
            start: {
                x: 0,
                y: 0
            },
            current: {
                x: 0,
                y: 0
            }
        },
        bottom: {
            start: {
                x: 0,
                y: 0
            },
            current: {
                x: 0,
                y: 0
            }
        }
    }
    init = () => {
        this.containerRef.current.style.width = this.imgInfo.width + 'px'
        this.containerRef.current.style.height = this.imgInfo.height + 'px'
        let scale = 1
        if (this.cropBoxInfo.currentHeight > this.cropBoxInfo.currentWidth) {
            scale = this.cropBoxInfo.currentWidth/this.cropBoxInfo.currentHeight
            this.prevviewContainer.current.style.width = this.props.size*scale + 'px'
            this.prevviewContainer.current.style.height = this.props.size + 'px'
        } else {
            scale = this.cropBoxInfo.currentHeight/this.cropBoxInfo.currentWidth
            this.prevviewContainer.current.style.width = this.props.size + 'px'
            this.prevviewContainer.current.style.height = this.props.size*scale + 'px'
        }
        if (this.cropBoxInfo.width > this.cropBoxInfo.height) {
            scale = this.props.size/this.cropBoxInfo.width
        } else {
            scale = this.props.size/this.cropBoxInfo.height
        }
        const left = this.cropBoxInfo.translateX
        const top = this.cropBoxInfo.translateY
        this.prevviewContainer.current.children[0].style.transform = `translate3d(${-left*scale + 'px'}, ${-top*scale + 'px'}, 0) scale(${this.imgInfo.width/this.imgInfo.naturalWidth*scale})`
        this.cropBoxRef.current.style.width = this.cropBoxViewRef.current.style.width = this.cropBoxInfo.width + 'px'
        this.cropBoxRef.current.style.height = this.cropBoxViewRef.current.style.height = this.cropBoxInfo.height + 'px'
        this.cropBoxRef.current.children[0].style.transform = `translate3d(${-left + 'px'}, ${-top + 'px'}, 0) scale(${this.imgInfo.width/this.imgInfo.naturalWidth})`
        this.cropBoxViewRef.current.style.transform = this.cropBoxRef.current.style.transform = `translate3d(${left + 'px'}, ${top + 'px'}, 0)`
    }
    load = e => {
        let { naturalWidth, naturalHeight } = e.target
        this.imgInfo.naturalWidth = naturalWidth
        this.imgInfo.naturalHeight = naturalHeight
        if(naturalWidth > naturalHeight){
            this.imgInfo.width = this.props.size
            this.imgInfo.height = this.props.size*naturalHeight/naturalWidth
        }else if (naturalWidth < naturalHeight){
            this.imgInfo.width = this.props.size*naturalWidth/naturalHeight
            this.imgInfo.height = this.props.size
        }else{
            this.imgInfo.height = this.imgInfo.width = this.props.size
        }
        this.setSize(1, 1)

        if(this.src){
            URL.revokeObjectURL(this.src)
            this.src = null
        }
        this.setState({
            hasImg: true
        }, () => {
            this.cropBoxRef.current.style.visibility = 'visible'
            this.cropBoxViewRef.current.style.visibility = 'visible'
        })
    }
    cropBoxMouseDown = e => {
        this.isCropBoxMouse = true
        this.cropBoxInfo.start = {
            x: e.pageX,
            y: e.pageY
        }
        window.addEventListener('mousemove', this.cropBoxMouseMove)
        window.addEventListener('mouseup', this.cropBoxMouseUp)
    }
    cropBoxMouseMove = e => {
        if(this.isCropBoxMouse){
            if(this.timer){
                cancelAnimationFrame(this.timer)
            }
            this.timer = window.requestAnimationFrame(() => {
                this.cropBoxInfo.current = {
                    x: e.pageX,
                    y: e.pageY
                }
                let distanceX = 0, distanceY = 0
                distanceX = this.cropBoxInfo.current.x - this.cropBoxInfo.start.x
                distanceY = this.cropBoxInfo.current.y - this.cropBoxInfo.start.y
                this.cropBoxInfo.translateX = this.cropBoxInfo.left + distanceX
                this.cropBoxInfo.translateY = this.cropBoxInfo.top + distanceY
                let left = this.cropBoxInfo.translateX
                let top = this.cropBoxInfo.translateY
                let width = parseFloat(this.cropBoxRef.current.style.width)
                let height = parseFloat(this.cropBoxRef.current.style.height)
                if(left < 0) {
                    this.cropBoxInfo.left = this.cropBoxInfo.translateX = 0
                    this.cropBoxInfo.start.x = this.cropBoxInfo.current.x
                }else{
                    if(left > (this.imgInfo.width - width)){
                        this.cropBoxInfo.left = this.cropBoxInfo.translateX = this.imgInfo.width - width
                        this.cropBoxInfo.start.x = this.cropBoxInfo.current.x
                    }
                }
                if(top < 0) {
                    this.cropBoxInfo.top = this.cropBoxInfo.translateY = 0
                    this.cropBoxInfo.start.y = this.cropBoxInfo.current.y
                }else{
                    if(top > (this.imgInfo.height - height)){
                        this.cropBoxInfo.top = this.cropBoxInfo.translateY = this.imgInfo.height - height
                        this.cropBoxInfo.start.y = this.cropBoxInfo.current.y
                    }
                }
                left = this.cropBoxInfo.translateX
                top = this.cropBoxInfo.translateY
                this.cropBoxViewRef.current.style.transform = this.cropBoxRef.current.style.transform = `translate3d(${left + 'px'}, ${top + 'px'}, 0)`
                this.cropBoxRef.current.children[0].style.transform = `translate3d(${-left + 'px'}, ${-top + 'px'}, 0) scale(${this.imgInfo.width/this.imgInfo.naturalWidth})`
                let scale = 1
                if (width > height) {
                    scale = this.props.size/width
                } else {
                    scale = this.props.size/height
                }
                this.prevviewContainer.current.children[0].style.transform = `translate3d(${-left*scale + 'px'}, ${-top*scale + 'px'}, 0) scale(${this.imgInfo.width/this.imgInfo.naturalWidth*scale})`
            })
        }
    }
    cropBoxMouseUp = () => {
        if(this.timer){
            cancelAnimationFrame(this.timer)
            this.timer = null
        }
        this.isCropBoxMouse = false
        this.cropBoxInfo.left = this.cropBoxInfo.translateX
        this.cropBoxInfo.top = this.cropBoxInfo.translateY
        window.removeEventListener('mousemove', this.cropBoxMouseMove)
        window.removeEventListener('mouseup', this.cropBoxMouseUp)
    }
    pointMouseDown = (e, point) => {
        e.stopPropagation()
        this.point = point
        this.isPointMouse = true
        this.pointInfo[this.point].start = {
            x: e.pageX,
            y: e.pageY
        }
        window.addEventListener('mousemove', this.pointMouseMove)
        window.addEventListener('mouseup', this.pointMouseUp)
    }
    pointMouseMove = e => {
        e.stopPropagation()
        if(this.timer){
            window.cancelAnimationFrame(this.timer)
            this.timer = null
        }
        if(this.isPointMouse){
            this.timer = window.requestAnimationFrame(() => {
                this.timer = null
                if(!this.point) {
                    return
                }
                this.pointInfo[this.point].current = {
                    x: e.pageX,
                    y: e.pageY
                }
                let distanceX = 0, distanceY = 0, _distanceX = 0, _distanceY = 0
                distanceX = this.pointInfo[this.point].current.x - this.pointInfo[this.point].start.x
                distanceY = this.pointInfo[this.point].current.y - this.pointInfo[this.point].start.y
                let distance = 0
                if (this.point === 'leftTop' || this.point === 'rightTop' || this.point === 'rightBottom' || this.point === 'leftBottom') {
                    _distanceY = Math.abs(distanceY)
                    _distanceX = Math.abs(distanceY)*this.state.w/this.state.h
                }
                if (this.point === 'left' || this.point === 'right') {
                    distance = Math.abs(distanceX)
                }
                if (this.point === 'top' || this.point === 'bottom') {
                    distance = Math.abs(distanceY)
                }
                if(this.point === 'left'){
                    if(distanceX > 0){
                        this.cropBoxInfo.translateX = this.cropBoxInfo.left + distance
                        this.cropBoxInfo.currentWidth = this.cropBoxInfo.width - distance
                        if(this.cropBoxInfo.currentWidth < 24){
                            this.cropBoxInfo.currentWidth = 24
                            this.cropBoxInfo.translateX = this.cropBoxInfo.left + this.cropBoxInfo.width - 24
                        }
                    }
                    if(distanceX < 0){
                        this.cropBoxInfo.translateX = this.cropBoxInfo.left - distance
                        this.cropBoxInfo.currentWidth = this.cropBoxInfo.width + distance
                    }
                    if(this.cropBoxInfo.translateX < 0){
                        let over = this.cropBoxInfo.translateX
                        this.cropBoxInfo.translateX = 0
                        this.cropBoxInfo.currentWidth += over
                    }
                }else if(this.point === 'right'){
                    if(distanceX > 0){
                        this.cropBoxInfo.currentWidth = this.cropBoxInfo.width + distance
                    }
                    if(distanceX < 0){
                        this.cropBoxInfo.currentWidth = this.cropBoxInfo.width - distance
                        if(this.cropBoxInfo.currentWidth < 24){
                            this.cropBoxInfo.currentWidth = 24
                        }
                    }
                    if(this.cropBoxInfo.translateX + this.cropBoxInfo.currentWidth > this.imgInfo.width){
                        let over = this.imgInfo.width - this.cropBoxInfo.currentWidth - this.cropBoxInfo.translateX
                        this.cropBoxInfo.currentWidth += over
                    }
                }else if(this.point === 'bottom'){
                    if(distanceY > 0){
                        this.cropBoxInfo.currentHeight = this.cropBoxInfo.height + distance
                    }
                    if(distanceY < 0){
                        this.cropBoxInfo.currentHeight = this.cropBoxInfo.height - distance
                        if(this.cropBoxInfo.currentHeight < 24){
                            this.cropBoxInfo.currentHeight = 24
                        }
                    }
                    if(this.cropBoxInfo.translateY + this.cropBoxInfo.currentHeight > this.imgInfo.height){
                        let over = this.imgInfo.height - this.cropBoxInfo.currentHeight - this.cropBoxInfo.translateY
                        this.cropBoxInfo.currentHeight += over
                    }
                }else if(this.point === 'top'){
                    if(distanceY > 0){
                        this.cropBoxInfo.translateY = this.cropBoxInfo.top + distance
                        this.cropBoxInfo.currentHeight = this.cropBoxInfo.height - distance
                        if(this.cropBoxInfo.currentHeight < 24){
                            this.cropBoxInfo.currentHeight = 24
                            this.cropBoxInfo.translateY = this.cropBoxInfo.top + this.cropBoxInfo.height - 24
                        }
                    }
                    if(distanceY < 0){
                        this.cropBoxInfo.translateY = this.cropBoxInfo.top - distance
                        this.cropBoxInfo.currentHeight = this.cropBoxInfo.height + distance
                    }
                    if(this.cropBoxInfo.translateY < 0){
                        let over = this.cropBoxInfo.translateY
                        this.cropBoxInfo.translateY = 0
                        this.cropBoxInfo.currentHeight += over
                    }
                }else if(this.point === 'leftTop'){
                    if(!((distanceY > 0 && distanceX > 0) || (distanceY < 0 && distanceX < 0))){
                        return
                    }
                    if(distanceY > 0 && distanceX > 0){
                        if (this.cropBoxInfo.currentWidth > 24 && this.cropBoxInfo.currentHeight > 24) {
                            this.cropBoxInfo.translateX = this.cropBoxInfo.left + _distanceX
                            this.cropBoxInfo.translateY = this.cropBoxInfo.top + _distanceY
                            this.cropBoxInfo.currentWidth = this.cropBoxInfo.width - _distanceX
                            this.cropBoxInfo.currentHeight = this.cropBoxInfo.height - _distanceY
                        }
                        if(this.cropBoxInfo.currentWidth < 24){
                            this.cropBoxInfo.currentWidth = 24
                            this.cropBoxInfo.translateX = this.cropBoxInfo.left + this.cropBoxInfo.width - 24
                        }
                        if(this.cropBoxInfo.currentHeight < 24){
                            this.cropBoxInfo.currentHeight = 24
                            this.cropBoxInfo.translateY = this.cropBoxInfo.top + this.cropBoxInfo.height - 24
                        }
                    }
                    if(distanceY < 0 && distanceX < 0){
                        this.cropBoxInfo.translateX = this.cropBoxInfo.left - _distanceX
                        this.cropBoxInfo.translateY = this.cropBoxInfo.top - _distanceY
                        this.cropBoxInfo.currentWidth = this.cropBoxInfo.width + _distanceX
                        this.cropBoxInfo.currentHeight = this.cropBoxInfo.height + _distanceY
                    }
                    if(this.cropBoxInfo.translateX < 0){
                        let overX= this.cropBoxInfo.translateX
                        let overY = overX*this.state.h/this.state.w
                        this.cropBoxInfo.translateX = 0
                        this.cropBoxInfo.translateY -= overY
                        this.cropBoxInfo.currentWidth += overX
                        this.cropBoxInfo.currentHeight += overY
                    }
                    if(this.cropBoxInfo.translateY < 0){
                        let overY = this.cropBoxInfo.translateY
                        let overX = overY*this.state.w/this.state.h
                        this.cropBoxInfo.translateY = 0
                        this.cropBoxInfo.translateX -= overX
                        this.cropBoxInfo.currentWidth += overX
                        this.cropBoxInfo.currentHeight += overY
                    }
                }else if(this.point === 'rightTop'){
                    if(!((distanceY > 0 && distanceX < 0) || (distanceY < 0 && distanceX > 0))){
                        return
                    }
                    if(distanceX > 0 && distanceY < 0){
                        this.cropBoxInfo.translateY = this.cropBoxInfo.top - _distanceY
                        this.cropBoxInfo.currentWidth = this.cropBoxInfo.width + _distanceX
                        this.cropBoxInfo.currentHeight = this.cropBoxInfo.height + _distanceY
                    }
                    if(distanceX < 0 && distanceY > 0){
                        if (this.cropBoxInfo.currentWidth > 24 && this.cropBoxInfo.currentHeight > 24) {
                            this.cropBoxInfo.translateY = this.cropBoxInfo.top + _distanceY
                            this.cropBoxInfo.currentWidth = this.cropBoxInfo.width - _distanceX
                            this.cropBoxInfo.currentHeight = this.cropBoxInfo.height - _distanceY
                        }
                        if(this.cropBoxInfo.currentWidth < 24){
                            this.cropBoxInfo.currentWidth = 24
                        }
                        if(this.cropBoxInfo.currentHeight < 24){
                            this.cropBoxInfo.currentHeight = 24
                            this.cropBoxInfo.translateY = this.cropBoxInfo.top + this.cropBoxInfo.height - 24
                        }
                    }
                    if(this.cropBoxInfo.translateY < 0){
                        let overY = this.cropBoxInfo.translateY
                        let overX = overY*this.state.w/this.state.h
                        this.cropBoxInfo.translateY = 0
                        this.cropBoxInfo.currentWidth += overX
                        this.cropBoxInfo.currentHeight += overY
                    }
                    if(this.cropBoxInfo.translateX + this.cropBoxInfo.currentWidth > this.imgInfo.width){
                        let overX = this.imgInfo.width - this.cropBoxInfo.currentWidth - this.cropBoxInfo.translateX
                        let overY = overX*this.state.h/this.state.w
                        this.cropBoxInfo.translateY -= overY
                        this.cropBoxInfo.currentWidth += overX
                        this.cropBoxInfo.currentHeight += overY
                    }
                }else if(this.point === 'rightBottom'){
                    if(!((distanceY > 0 && distanceX > 0) || (distanceY < 0 && distanceX < 0))){
                        return
                    }
                    if(distanceY > 0 && distanceX > 0){
                        this.cropBoxInfo.currentWidth = this.cropBoxInfo.width + _distanceX
                        this.cropBoxInfo.currentHeight = this.cropBoxInfo.height + _distanceY
                    }
                    if(distanceY < 0 && distanceX < 0){
                        if (this.cropBoxInfo.currentWidth > 24 && this.cropBoxInfo.currentHeight > 24) {
                            this.cropBoxInfo.currentWidth = this.cropBoxInfo.width - _distanceX
                            this.cropBoxInfo.currentHeight = this.cropBoxInfo.height - _distanceY
                        }
                        if(this.cropBoxInfo.currentWidth < 24){
                            this.cropBoxInfo.currentWidth = 24
                        }
                        if(this.cropBoxInfo.currentHeight < 24){
                            this.cropBoxInfo.currentHeight = 24
                        }
                    }
                    if(this.cropBoxInfo.translateX + this.cropBoxInfo.currentWidth > this.imgInfo.width){
                        let overX = this.imgInfo.width - this.cropBoxInfo.currentWidth - this.cropBoxInfo.translateX
                        let overY = overX*this.state.h/this.state.w
                        this.cropBoxInfo.currentWidth += overX
                        this.cropBoxInfo.currentHeight += overY
                    }
                    if(this.cropBoxInfo.translateY + this.cropBoxInfo.currentHeight > this.imgInfo.height){
                        let overY = this.imgInfo.height - this.cropBoxInfo.currentHeight - this.cropBoxInfo.translateY
                        let overX = overY*this.state.w/this.state.h
                        this.cropBoxInfo.currentWidth += overX
                        this.cropBoxInfo.currentHeight += overY
                    }
                }else if(this.point === 'leftBottom'){
                    if(!((distanceY > 0 && distanceX < 0) || (distanceY < 0 && distanceX > 0))){
                        return
                    }
                    if(distanceY > 0 && distanceX < 0){
                        this.cropBoxInfo.translateX = this.cropBoxInfo.left - _distanceX
                        this.cropBoxInfo.currentWidth = this.cropBoxInfo.width + _distanceX
                        this.cropBoxInfo.currentHeight = this.cropBoxInfo.height + _distanceY
                    }
                    if(distanceY < 0 && distanceX > 0){
                        if (this.cropBoxInfo.currentWidth > 24 && this.cropBoxInfo.currentHeight > 24) {
                            this.cropBoxInfo.translateX = this.cropBoxInfo.left + _distanceX
                            this.cropBoxInfo.currentWidth = this.cropBoxInfo.width - _distanceX
                            this.cropBoxInfo.currentHeight = this.cropBoxInfo.height - _distanceY
                        }
                        if(this.cropBoxInfo.currentWidth < 24){
                            this.cropBoxInfo.currentWidth = 24
                            this.cropBoxInfo.translateX = this.cropBoxInfo.left + this.cropBoxInfo.width - 24
                        }
                        if(this.cropBoxInfo.currentHeight < 24){
                            this.cropBoxInfo.currentHeight = 24
                        }
                    }
                    if(this.cropBoxInfo.translateX < 0){
                        let overX = this.cropBoxInfo.translateX
                        let overY = overX*this.state.h/this.state.w
                        this.cropBoxInfo.translateX = 0
                        this.cropBoxInfo.currentWidth += overX
                        this.cropBoxInfo.currentHeight += overY
                    }
                    if(this.cropBoxInfo.translateY + this.cropBoxInfo.currentHeight > this.imgInfo.height){
                        let overY = this.imgInfo.height - this.cropBoxInfo.currentHeight - this.cropBoxInfo.translateY
                        let overX = overY*this.state.w/this.state.h
                        this.cropBoxInfo.translateX -= overX
                        this.cropBoxInfo.currentWidth += overX
                        this.cropBoxInfo.currentHeight += overY
                    }
                }
                this.cropBoxViewRef.current.style.transform = this.cropBoxRef.current.style.transform = `translate3d(${this.cropBoxInfo.translateX + 'px'}, ${this.cropBoxInfo.translateY + 'px'}, 0)`
                this.cropBoxRef.current.style.width = this.cropBoxViewRef.current.style.width = this.cropBoxInfo.currentWidth + 'px'
                this.cropBoxRef.current.style.height = this.cropBoxViewRef.current.style.height = this.cropBoxInfo.currentHeight + 'px'
                let left = this.cropBoxInfo.translateX
                let top = this.cropBoxInfo.translateY
                this.cropBoxRef.current.children[0].style.transform = `translate3d(${-left + 'px'}, ${-top + 'px'}, 0) scale(${this.imgInfo.width/this.imgInfo.naturalWidth})`
                if (this.cropBoxInfo.currentHeight > this.cropBoxInfo.currentWidth) {
                    let scale = this.props.size/this.cropBoxInfo.currentHeight
                    this.prevviewContainer.current.children[0].style.transform = `translate3d(${-left*scale + 'px'}, ${-top*scale + 'px'}, 0) scale(${this.imgInfo.width/this.imgInfo.naturalWidth*scale})`
                    scale = this.cropBoxInfo.currentWidth/this.cropBoxInfo.currentHeight
                    this.prevviewContainer.current.style.width = this.props.size*scale + 'px'
                    this.prevviewContainer.current.style.height = this.props.size + 'px'
                } else {
                    let scale = this.props.size/this.cropBoxInfo.currentWidth
                    this.prevviewContainer.current.children[0].style.transform = `translate3d(${-left*scale + 'px'}, ${-top*scale + 'px'}, 0) scale(${this.imgInfo.width/this.imgInfo.naturalWidth*scale})`
                    scale = this.cropBoxInfo.currentHeight/this.cropBoxInfo.currentWidth
                    this.prevviewContainer.current.style.width = this.props.size + 'px'
                    this.prevviewContainer.current.style.height = this.props.size*scale + 'px'
                }
                if (this.point === 'left' || this.point === 'right' || this.point === 'top' || this.point === 'bottom') {
                    this.setState({
                        w: (this.cropBoxInfo.currentWidth/this.cropBoxInfo.currentHeight).toFixed(3),
                        h: 1
                    })
                }
            })
        }
    }
    pointMouseUp = () => {
        if(this.timer){
            window.cancelAnimationFrame(this.timer)
            this.timer = null
        }
        this.cropBoxInfo.left = this.cropBoxInfo.translateX
        this.cropBoxInfo.top = this.cropBoxInfo.translateY
        this.cropBoxInfo.width = this.cropBoxInfo.currentWidth
        this.cropBoxInfo.height = this.cropBoxInfo.currentHeight
        this.point = ''
        this.isPointMouse = false
        window.removeEventListener('mousemove', this.pointMouseMove)
        window.removeEventListener('mouseup', this.pointMouseUp)
    }
    getFile = file => {
        this.src = URL.createObjectURL(file[0])
        this.mainImgRef.current.src = this.cropBoxRef.current.children[0].src = this.prevviewContainer.current.children[0].src = this.src
    }
    confirm = () => {
        imgToBase64({
            img: this.mainImgRef.current,
            left: this.cropBoxInfo.translateX,
            top: this.cropBoxInfo.translateY,
            width: parseFloat(this.cropBoxRef.current.style.width),
            height: parseFloat(this.cropBoxRef.current.style.height),
            success: res => {
                this.props.success(res)
            }
        })
    }
    setSize = (w, h) => {
        this.setState({
            w,
            h
        })
        if (this.imgInfo.width > this.imgInfo.height) {
            if (this.imgInfo.width/this.imgInfo.height > w/h) {
                this.cropBoxInfo.currentHeight = this.cropBoxInfo.height = this.imgInfo.height
                this.cropBoxInfo.currentWidth = this.cropBoxInfo.width = w/h*this.imgInfo.height
                this.cropBoxInfo.left = this.cropBoxInfo.translateX = (this.imgInfo.width - this.cropBoxInfo.width)/2
                this.cropBoxInfo.top = this.cropBoxInfo.translateY = 0
            } else {
                this.cropBoxInfo.currentHeight = this.cropBoxInfo.height = h/w*this.imgInfo.width
                this.cropBoxInfo.currentWidth = this.cropBoxInfo.width = this.imgInfo.width
                this.cropBoxInfo.left = this.cropBoxInfo.translateX = 0
                this.cropBoxInfo.top = this.cropBoxInfo.translateY = (this.imgInfo.height - this.cropBoxInfo.height)/2
            }
        } else {
            if (this.imgInfo.height/this.imgInfo.width > h/w) {
                this.cropBoxInfo.currentHeight = this.cropBoxInfo.height = h/w*this.imgInfo.width
                this.cropBoxInfo.currentWidth = this.cropBoxInfo.width = this.imgInfo.width
                this.cropBoxInfo.left = this.cropBoxInfo.translateX = 0
                this.cropBoxInfo.top = this.cropBoxInfo.translateY = (this.imgInfo.height - this.cropBoxInfo.height)/2
            } else {
                this.cropBoxInfo.currentHeight = this.cropBoxInfo.height = this.imgInfo.height
                this.cropBoxInfo.currentWidth = this.cropBoxInfo.width = w/h*this.imgInfo.height
                this.cropBoxInfo.left = this.cropBoxInfo.translateX = (this.imgInfo.width - this.cropBoxInfo.width)/2
                this.cropBoxInfo.top = this.cropBoxInfo.translateY = 0
            }
        }
        this.init()
    }
    render(){
        return(
            <div className={ cssStyle.main }>
                <div className={ cssStyle.crop }>
                    <div className={ cssStyle.left } style={{ width: this.props.size, height: this.props.size }}>
                        <div className={ cssStyle.modal } style={{ visibility: this.state.hasImg ? 'visible' : 'hidden' }}></div>
                        <div className={ cssStyle.container } ref={ this.containerRef }>
                            <img
                                className={ cssStyle.mainImg }
                                ref={ this.mainImgRef }
                                src={ this.props.src ? this.props.src : '' }
                                draggable={ false }
                                onLoad={ this.load }
                                onDragStart={ () => { return false } }
                            />
                            <div className={ cssStyle.cropbox } ref={ this.cropBoxRef }>
                                <img
                                    src={ this.props.src ? this.props.src : '' }
                                    draggable={false}
                                    onDragStart={ () => { return false } }
                                />
                            </div>
                            <div className={ cssStyle.cropboxView } ref={ this.cropBoxViewRef } onMouseDown={ this.cropBoxMouseDown }>
                                <span
                                    onMouseDown={ e => { this.pointMouseDown(e, 'leftTop') } }
                                ></span>
                                <span
                                    onMouseDown={ e => { this.pointMouseDown(e, 'rightTop') } }
                                ></span>
                                <span
                                    onMouseDown={ e => { this.pointMouseDown(e, 'rightBottom') } }
                                ></span>
                                <span
                                    onMouseDown={ e => { this.pointMouseDown(e, 'leftBottom') } }
                                ></span>
                                <span
                                    onMouseDown={ e => { this.pointMouseDown(e, 'left') } }
                                ></span>
                                <span
                                    onMouseDown={ e => { this.pointMouseDown(e, 'right') } }
                                ></span>
                                <span
                                    onMouseDown={ e => { this.pointMouseDown(e, 'top') } }
                                ></span>
                                <span
                                    onMouseDown={ e => { this.pointMouseDown(e, 'bottom') } }
                                ></span>
                            </div>
                        </div>
                    </div>
                    <div className={ cssStyle.right } style={{ width: this.props.size, height: this.props.size }}>
                        <div className={ cssStyle.prevview } ref={ this.prevviewContainer }>
                            <img
                                src={ this.props.src ? this.props.src : '' }
                            />
                        </div>
                    </div>
                </div>
                <div className={ cssStyle.contorl }>
                    {
                        this.state.hasImg
                        ?
                        <>
                            <div style={{ textAlign: 'center' }}>
                                <Button type="primary" size="small" onClick={ () => { this.setSize(16, 9) } }>16:9</Button>
                                <Button type="primary" size="small" onClick={ () => { this.setSize(4, 3) } } style={{ marginLeft: 12 }}>4:3</Button>
                                <Button type="primary" size="small" onClick={ () => { this.setSize(1, 1) } } style={{ marginLeft: 12 }}>1:1</Button>
                                <Button type="primary" size="small" onClick={ () => { this.setSize(3, 4) } } style={{ marginLeft: 12 }}>3:4</Button>
                                <Button type="primary" size="small" onClick={ () => { this.setSize(9, 16) } } style={{ marginLeft: 12 }}>9:16</Button>
                                <Form.input value={ this.state.w } style={{ marginLeft: 12, marginRight: 4, width: 64, textAlign: 'center', lineHeight: '30px' }}
                                    onChange={ val => { this.setState({w: val}) } }
                                />
                                <span>:</span>
                                <Form.input value={ this.state.h } style={{ marginLeft: 4, width: 64, textAlign: 'center', lineHeight: '30px' }}
                                    onChange={ val => { this.setState({h: val}) } }
                                />
                                <Button type="primary" size="small" disabled={ !parseFloat(this.state.w) || !parseFloat(this.state.h) } onClick={ () => { this.setSize(parseFloat(this.state.w), parseFloat(this.state.h)) } } style={{ marginLeft: 4 }}>确定</Button>
                            </div>
                            <div style={{ textAlign: 'center', marginTop: 8 }}>
                                <Form.upload onChange={ this.getFile } showFileName={ false }>
                                    <Button type="primary" size="small">更换图片</Button>
                                </Form.upload>
                                <Button type="success" size="small" onClick={ this.confirm } style={{ marginLeft: 12 }}>确定</Button>
                            </div>
                        </>
                        :
                        <Form.upload onChange={ this.getFile } showFileName={ false }>
                            <Button type="primary" size="small">上传图片</Button>
                        </Form.upload>
                    }
                </div>
            </div>
        )
    }
}

Crop.propTypes = {
    src: PropTypes.string,
    success: PropTypes.func
}
Crop.defaultProps = {
    size: 250
}

export default Crop